<?php
final class XI18N{
	private static $instance = null;
	private $holder = null;
	private $locales = array();
	private $messages = array();
	
	private function __construct() {
		$dir = PROJECT_ROOT.'/i18n';
		if(!is_dir($dir)){
			return;
		}
		$handler = @opendir($dir);
		if(!$handler){
			return;
		}
		while($file = @readdir($handler)){
			if(in_array($file, array('.', '..'))){
				continue;
			}
			$path = $dir.'/'.$file;
			if(is_dir($path)){
				$this->locales[$file] = $file;
				$this->loadMessages($file, $path);
			}
		}
	    @closedir($handler);
	}
	
	/**
	 * @return XI18N
	 */	
	public static function singleton() {
		if (!self::$instance) {
			self::$instance = new self;
		}
		return self::$instance;
	}
	
	protected function loadMessages($locale, $dir){
		if(!is_dir($dir)){
			return;
		}
		$handler = @opendir($dir);
		if(!$handler){
			return;
		}
		while($file = @readdir($handler)){
			if(in_array($file, array('.', '..'))){
				continue;
			}
			$path = $dir.'/'.$file;
			if(!is_file($path)){
				continue;
			}
			$loader = XFactory::singleton()->get('XINIConfigLoader');
			$results = $loader->load($path);
			foreach($results as $key => $value){
				x_array_set($this->messages, "project.i18n.{$locale}.{$key}", $value);
			}
		}
	    @closedir($handler);
	}
	
	/**
	 * @return mixed
	 */	
	public function message($key){
		$locale = $this->getLocale();
		if(is_null($locale)){
			return null;
		}
		return x_array_get($this->messages, "project.i18n.{$locale}.{$key}");
	}
	
	/**
	 * @return XI18N
	 */		
	public function setHolder(XLocaleHolder $holder){
		$this->holder = $holder;
		return $this;
	}
	
	/**
	 * @return XLocaleHolder
	 */	
	public function holder(){
		if(is_null($this->holder)){
			$this->load();
		}
		return $this->holder;
	}	
	
	/**
	 * @return mixed
	 */	
	public function getLocale(){
		$locale = $this->holder()->getLocale();
		//equals
		$locale = str_replace('-', '_', strtolower($locale));
		foreach($this->locales as $value){
			if($locale == $value){
				return $locale;
			}
		}
		//match
		$language = preg_split('/[-_]+/i', $locale);
		$language = $language[0];
		foreach($this->locales as $value){
			$result = preg_split('/[-_]+/i', $locale);
			$result = $result[0];
			if($result == $language){
				return $locale;
			}
		}
		return $this->defaultLocale();
	}
	
	/**
	 * @return XI18N
	 */	
	public function setLocale($locale){
		$this->holder()->setLocale($locale);
		return $this;
	}
	
	protected function load(){
		//load holder class
		$class = XConfig::singleton()->get('project.i18n.holder.class');
		if(class_exists($class, false)){
			if(XClassLoader::loader($class)->implementsInterface('XLocaleHolder')){
				$this->setHolder(XFactory::singleton()->get($class));
				return true;
			}
		}
		//load default holder
		$holder = XFactory::singleton()->get('XHttpLocaleHolder');
		$this->setHolder($holder);
		return true;
	}
	
	/**
	 * @return mixed
	 */	
	public function defaultLocale(){
		$locale = XConfig::singleton()->get('project.i18n.locale.default');
		if(!$locale){
			$locale = x_array_head($this->locales);
		}
		return $locale;
	}
}
?>